﻿using Vowei.Data.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Vowei.Data.Models;
using Vowei.Data;
using Vowei.Data.Models.Statistics;
using System.Linq;
using System.IO;
using System.Collections.Generic;
using Vowei.Data.Converters.Excel;
using Vowei.Core.Models;
using Vowei.Core;

namespace vowei.test
{
    [TestClass()]
    public class StatisticsHelpersTest : TestBase
    {
        private Guid _TestProjectId = Guid.Empty;

        [TestInitialize]
        public void InitTest()
        {
            var filename = Path.Combine(
                TestContext.TestDeploymentDir, @"StatisticsHelpersTest_TopRequirementWorksBasicTest.xls");
            var project = CreateProjectHelper("TopRequirementWorksBasicTest");
            _TestProjectId = project.ID;

            using (var stream = File.Open(filename, FileMode.Open, FileAccess.Read))
            {
                var target = new WorkItemExcelConverter(VoweiContext.TicketStatusManager);
                var works = target.ConvertFrom(stream);

                using (var impl = new VoweiContextImpl())
                {
                    var context = new VoweiContext(impl);
                    project.ProjectBaseCalendar = context.ResourceCalendars.Find(Constants.BuiltIn.ResouceCalendar.StandardCalendarId);
                    impl.Projects.Add(project);
                    impl.SaveChanges();

                    ImportHelper.ImportDataTo(project, context, works, Setting.DefaultFormUser);
                    impl.SaveChanges();
                }
            }
        }

        [TestMethod()]
        public void TopRequirementWorksBasicTest()
        {
            using (var impl = new VoweiContextImpl())
            {
                var context = new VoweiContext(impl);
                // var project = impl.Projects.Find(_TestProjectId);
                var project = GetDefaultProject(context);
                var actual = project.TopRequirementWorks(context);
                var verifyItem = actual.First(a => string.Compare(a.Requirement.Title, "需求管理基本功能") == 0);

                Assert.AreEqual(24, actual.Length);
                Assert.AreEqual(3, verifyItem.ClosedTasksCount);
                Assert.AreEqual(10, verifyItem.ActiveTasksCount);
                Assert.AreEqual(0, verifyItem.ClosedRequirementsCount);
                Assert.AreEqual(2, verifyItem.ActiveRequirementsCount);

                verifyItem = actual.First(a => string.Compare(a.Requirement.Title, "整合配置管理系统") == 0);
                Assert.AreEqual(5, verifyItem.ClosedTasksCount);
                Assert.AreEqual(1, verifyItem.ClosedRequirementsCount);
                Assert.AreEqual(0, verifyItem.ActiveTasksCount);
                Assert.AreEqual(0, verifyItem.ActiveRequirementsCount);
            }
        }

        [TestMethod()]
        public void EarnedValuesBasicTest()
        {
            var project = CreateProjectHelper("EarnedValuesBasicTest");

            using (var impl = new VoweiContextImpl())
            {
                var context = new VoweiContext(impl);
                var employee = context.Employees.Find("yimin_shi@hotmail.com");
                if (employee == null)
                {
                    employee = new Employee
                    {
                        DisplayName = "施懿民",
                        Email = "yimin_shi@hotmail.com"
                    };
                    context.Employees.Add(employee);
                }
                project.ProjectBaseCalendar = context.ResourceCalendars.Find(Constants.BuiltIn.ResouceCalendar.StandardCalendarId);
                context.Assignments.Add(new ResourceAssignment
                {
                    ResourceId = employee.ID,
                    ProjectId = project.ID,
                    WorkCalendar = project.ProjectBaseCalendar
                });
                context.Projects.Add(project);
                context.SaveChanges();

                ImportTestDataToProject(project, context,
                    Path.Combine(TestContext.TestDeploymentDir, @"EarnedValuesBasicTest.xls"));
                var actual = project.EarnedValues(context);
                Assert.AreEqual(9, actual.Length);

                var key = new EarnedValueStatistics() { Date = new DateTime(2010, 12, 14, 0, 0, 0) };
                var idx = Array.BinarySearch(actual, key);
                Assert.IsTrue(idx >= 0);
                Assert.AreEqual(10000, actual[idx].BCWS);
                Assert.AreEqual(10000, actual[idx].BCWP);

                key = new EarnedValueStatistics() { Date = new DateTime(2010, 12, 20, 0, 0, 0) };
                idx = Array.BinarySearch(actual, key);
                Assert.IsTrue(idx >= 0);
                Assert.AreEqual(10000, actual[idx].BCWS);
                Assert.AreEqual(20000, actual[idx].BCWP);

                key = new EarnedValueStatistics() { Date = new DateTime(2010, 12, 24, 0, 0, 0) };
                idx = Array.BinarySearch(actual, key);
                Assert.IsTrue(idx >= 0);
                Assert.AreEqual(10000, actual[idx].BCWS);
                Assert.AreEqual(60000, actual[idx].BCWP);

                key = new EarnedValueStatistics() { Date = new DateTime(2010, 12, 26, 0, 0, 0) };
                idx = Array.BinarySearch(actual, key);
                Assert.IsTrue(idx >= 0);
                Assert.AreEqual(20000, actual[idx].BCWS);
                Assert.AreEqual(60000, actual[idx].BCWP);

                // 计算工作时间
                key = new EarnedValueStatistics() { Date = new DateTime(2010, 12, 13, 0, 0, 0) };
                idx = Array.BinarySearch(actual, key);
                Assert.AreEqual(33, actual[idx].PlanedWorkHours.TotalHours);
                Assert.AreEqual(33, actual[idx].FinishedWorkHours.TotalHours);

                key = new EarnedValueStatistics() { Date = new DateTime(2010, 12, 14, 0, 0, 0) };
                idx = Array.BinarySearch(actual, key);
                Assert.AreEqual(41, actual[idx].PlanedWorkHours.TotalHours);
                Assert.AreEqual(41, actual[idx].FinishedWorkHours.TotalHours);

                key = new EarnedValueStatistics() { Date = new DateTime(2010, 12, 20, 0, 0, 0) };
                idx = Array.BinarySearch(actual, key);
                Assert.AreEqual(74, actual[idx].PlanedWorkHours.TotalHours);
                Assert.AreEqual(41, actual[idx].FinishedWorkHours.TotalHours);

                key = new EarnedValueStatistics() { Date = new DateTime(2010, 12, 26, 0, 0, 0) };
                idx = Array.BinarySearch(actual, key);
                Assert.AreEqual(106, actual[idx].PlanedWorkHours.TotalHours);
                Assert.AreEqual(58, actual[idx].FinishedWorkHours.TotalHours);

                key = new EarnedValueStatistics() { Date = new DateTime(2010, 12, 30, 0, 0, 0) };
                idx = Array.BinarySearch(actual, key);
                Assert.IsFalse(idx >= 0);
            }
        }
    }
}
